package com.cg.service.impl;

import com.cg.dao.ArrangeMapper;
import com.cg.dao.OrderMapper;
import com.cg.dao.PatientMapper;
import com.cg.dto.*;
import com.cg.entity.Arrange;
import com.cg.entity.Order;
import com.cg.entity.Patient;
import com.cg.service.NumService;
import com.cg.service.OrderService;
import com.cg.util.IdUtils;
import com.cg.vo.OrderDetailVo;
import com.cg.vo.OrderListVo;
import com.cg.vo.SendOrderNumByPhone;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * (Order)表服务实现类
 *
 * @author chengong
 * @since 2024-01-12 10:09:49
 */
@Service("orderService")
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;

    @Value("${orderCount}")
    private Integer orderCount;

    @Resource
    private IdUtils idUtils;

    @Resource
    private NumService numService;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private ArrangeMapper arrangeMapper;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Value("${orderTopic}")
    private String orderTopic;

    @Resource
    private PatientMapper patientMapper;
    /**
     * 患者预约
     */
    @Transactional
    @Override
    public Result createOrder(OrderDto orderDto) {
        //判断
        //查询一天之内，同一时段，同一患者是否有预约
        Integer count = orderMapper.queryCountByTimeFrame(orderDto);
        if(count > 0){
            //当天当前时段该患者已预约
            return ResultUtils.returnResult(ResultEnum.ORDER_EXIST);
        }

        //查询一天之内，同一患者预约的次数，不能超过3次
        orderDto.setTimeFrame(null);
        count = orderMapper.queryCountByTimeFrame(orderDto);
        if(count > orderCount){
            //当天该患者预约次数超过3次
            return ResultUtils.returnResult(ResultEnum.ORDER_COUNT_ERROR);
        }
        //生成预约编码
        String orderNum = idUtils.getCarNum();
        //生成预约二维码
        String code = numService.createCode(orderNum);

        //组装对象
        Order order = new Order();
        BeanUtils.copyProperties(orderDto,order);
        order.setOrderNum(orderNum);
        order.setCodePicUrl(code);

        Integer patientId = order.getPatientId();
        //根据patientId查询患者信息-获取患者的电话号码
        Patient patient = patientMapper.queryPatientById(patientId);
        if(patient == null){
            return ResultUtils.returnResult(ResultEnum.FAIL_HAVE_NOT_EXIST);
        }

        //加锁--分布式锁
        RLock lock = redissonClient.getLock(orderDto.getArrangeId().toString());
        try {
            boolean locked = lock.tryLock();
            if(locked){
                //查询余号数
                Arrange arrange = arrangeMapper.querySurplusByArrangeId(orderDto.getArrangeId());
                int index = arrange.getCountNum() - arrange.getSurplus();
                //减余号
                count = arrangeMapper.updateArrangeByArrangeId(orderDto.getArrangeId());
                if(count == 0){
                    return ResultUtils.returnResult(ResultEnum.FAIL_ORDER);
                }
                order.setOrderIndex(index);
                order.setOrderState(1);
                //新增预约
                orderMapper.createOrder(order);

                //组装对象
                SendOrderNumByPhone sendOrderNumByPhone = new SendOrderNumByPhone();
                sendOrderNumByPhone.setPhone(patient.getPhone());
                sendOrderNumByPhone.setOrderNum(orderNum);
                //发送消息 到RocketMQ的topic主题
                rocketMQTemplate.convertAndSend(orderTopic,sendOrderNumByPhone);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(lock != null && lock.isLocked()){
                if(lock.isHeldByCurrentThread()){
                    lock.unlock();
                }
            }
        }

        return ResultUtils.returnSuccess();
    }

    /**
     * 查询预约成功通知列表
     */
    @Override
    public PageInfo<OrderListVo> orderListByPatientId(OrderListPageDto orderListPageDto) {
        PageHelper.startPage(orderListPageDto.getPageNum(),orderListPageDto.getPageSize());
        List<OrderListVo> orderListVos = orderMapper.orderListByPatientId(orderListPageDto.getPatientId());
        PageInfo<OrderListVo> pageInfo = new PageInfo<>(orderListVos);
        return pageInfo;
    }


    /**
     * 根据orderNum查询详情
     */
    @Override
    public OrderDetailVo queryOrderDetailByOrderNum(String orderNum) {
        return orderMapper.queryOrderDetailByOrderNum(orderNum);
    }
}
